;11. Asemblerio source'u syntax highlight'as.
;Skaito asemblerio iseities teksta, raso validu HTML faila, kuriame vaizduojamas tas asemblerinis failas nuspalvinant sintakses elementus: 
;zymes, instrukcijas, registrus, betarpisku reiksmiu ir eiluciu literalus, komentarus.
  
PARAM_LINE EQU 80h
SPACE EQU 20h
BUFSIZE EQU 1024
STDIN EQU 0
STDOUT EQU 1
CR EQU 13
LF EQU 10
HTML_START_LEN EQU 106
HTML_END_LEN EQU 20
TASM_DIR_LEN EQU 954
TASM_INS_LEN EQU 822
TASM_REG_LEN EQU 63
SPALVA_PRADZIA_LEN EQU 22
SPALVA_PABAIGA_LEN EQU 7

PRINT EQU 09h
FCREATE EQU 3Ch
FOPEN EQU 3Dh
FCLOSE EQU 3Eh
READ EQU 3Fh
WRITE EQU 40h
EXIT EQU 4Ch
GETPSP EQU 62h
  
SSEG SEGMENT
  DB 256 dup (?)
SSEG ENDS

DSEG SEGMENT
  params DB 256 dup (?)
  arg_count DW ?
  arg_start DW 256 dup (?)
  infile DW STDIN
  outfile DW STDOUT
  buffer1 DB BUFSIZE dup(?)
  buffer2 DB BUFSIZE dup(?)
  curr_symb_nr DW 0
  start_symb_nr DW 0
  curr_symb DB ?
  start_symb_nr_tasm DW 0
  symb_ilgis_tasm DW 0
  isviso_symb DW ?

  sht_TASM_WORDS_LEN DW ?
  sht_tasm_words_adr DW ?
  sht_highlight_type DB ?
  sht_spalva_pradzia DW ?
  
  error_msg DB 'Klaida',CR,LF,'$'
  pagalba_msg DB 'Pagalba',CR,LF,'$'
  html_start DB '<html><head><title>Asm source syntax highlight.</title></head><body bgcolor="#000000" text="#c0c0c0"><pre>'
  html_end DB '</pre></body></html>'
  highlight_type DB 0 ;0 - be tipo, 1 - direktyva, 2 - instrukcija, 3 - registrai, 4 - label'is, 5 - skaicius, 6 - kabutes, 7 - komentaras
  bendras_highlight_type DB 0
  spalva_pradzia_dir DB '<font color="#ff80ff">'
  spalva_pradzia_ins DB '<font color="#ffff60">'
  spalva_pradzia_reg DB '<font color="#40ffff">'
  spalva_pradzia_label_var DB '<font color="#60AAAA">'
  spalva_pradzia_sk DB '<font color="#dda0a0">'
  spalva_pradzia_kabute DB '<font color="#ffa0a0">'
  spalva_pradzia_komentaras DB '<font color="#80a0ff">'
  spalva_pabaiga DB '</font>'
  spalva_pink DB ''
  separators DB 1 dup(' ',13,10,';[](),:-+',27h)
  sep_count DB 13
  
  tasm_directives DB 'ALIAS ALIGN ARG ASSUME %BIN CATSRT CODESEG COMM %CONDS CONST %CREF %CREFALL %CREFREF %CREFUREF %CTLS DATASEG DB DD %DEPTH DF DISPLAY DOSSEG DP DQ DT DW ELSE EMUL END ENDIF ENDM ENDP ENDS ENUM EQU ERR EVEN EVENDATA EXITCODE EXITM EXTRN FARDATA FASTIMUL'
  tasm_directives_1 DB ' FLIPFLAG GETFIELD GLOBAL GOTO GROUP IDEAL %INCL INCLUDE INCLUDELIB INSTR IRP IRPC JUMPS LABEL LARGESTACK %LINUM %LIST LOCAL LOCALS MACRO %MACS MASKFLAG MASM MASM51 MODEL MULTERRS NAME %NEWPAGE %NOCONDS %NOCREF %NOCTLS NOEMUL %NOINCL NOJUMPS %NOLIST'
  tasm_directives_2 DB ' NOLOCA LS %NOMACS NOMASM51 NOMULTERRS NOSMART %NOSYMS %NOTRUNC NOWARN %PAGESIZE %PCNT PNO87 %POPLCTL POPSTATE PROC PROCDESC PROCTYPE PUBLIC PUBLICDLL PURGE %PUSHCTL PUSHSTATE QUIRKS RADIX RECORD RETCODE SEGMENT SETFIELD SETFLAG SIZESTR SMALLSTACK SMART'
  tasm_directives_3 DB ' STACK STARTUPCODE STRUC SUBSTR %SUBTTL %SYMS TABLE %TABSIZE TBLINIT TBLINST TBLPTR TESTFLAG %TEXT %TITLE %TRUNC TYPEDEF UDATASEG UFARDATA UNION USES VERSION WAR WHILE ?DEBUG byte word dword qword ptr '

  tasm_instructions DB 'AAA AAD AAM AAS ADC ADD AND ARPL BOUND BSF BSR BSWAP BT BTC BTR BTS CALL CBW CLC CLD CLI CLTS CMC CMP CMPXCHG CMPXCHG8B CPUID CWD CDQ CWDE DAA DAS DEC DIV ENTER RETN RETF F2XM1 IDIV IMUL IN INC INT INTO INVD INVLPG IRET JMP LAHF LAR LDS LEA LEAVE LES'
  tasm_instructions_1 DB ' LFS LGDT LGS LIDT LLDT LMSW LOCK LODSB LSL LSS LTR MOV MOVSX MOVZX MUL NEG NOP NOT OR OUT POP POPA POPAD POPF POPFD PUSH PUSHA PUSHAD PUSHF PUSHFD RCL RCR RDMSR RDPMC RDTSC REP RET ROL ROR RSM SAHF SAR SBB SGDT SHL SAL SHLD SHR SHRD SIDT SMSW STC STD'
  tasm_instructions_2 DB ' STI STR SUB TEST VERR VERW WBINVD WRMSR XADD XCHG XLAT XOR CMPS CMPSB CMPSW MOV MOVS MOVSB MOVSW SCAS SCASB SCASW STOS STOSB STOSW LODS LODSB LODSW LOOP LOOPE LOOPNE LOOPNZ LOOPZ '
  tasm_instructions_3 DB 'JA JAE JB JBE JC JCXZ JE JG JGE JL JLE JNA JNAE JNB JNBE JNC JNE JNG JNGE JNL JNLE JNO JNP JNS JNZ JO JP JPE JPO JS JZ REPE REPNE REPNZ REPZ '

  tasm_registers DB 'AX AH AL BX BH BL CX CH CL DX DH DL CS IP SS SP BP SI DI DS ES '
DSEG ENDS

CSEG SEGMENT
  ASSUME CS:CSEG, DS:DSEG, SS:SSEG
  
MAIN PROC FAR
  MOV AX, SSEG
  MOV SS, AX
  MOV AX, DSEG
  MOV DS, AX
  MOV ES, AX
  
  CALL get_params

  ;CMP arg_count, 2
  ;JNE Error1

  MOV BP, 1
  MOV AL, 'h'
  CMP AL, byte ptr [DS:BP]
  JE pagalba
  JMP testi_darba
pagalba:
  LEA DX, pagalba_msg
  MOV AH, PRINT
  INT 21h
  JMP quit  

testi_darba:
  MOV AH, FOPEN
  XOR AL, AL
  MOV DX, arg_start[0]
  INT 21h
  JC Error1
  MOV infile, AX

  MOV AH, FCREATE
  XOR CX, CX
  MOV DX, arg_start[2]
  INT 21h
  JC Error1
  
  MOV AH, FOPEN
  MOV AL, 1
  MOV DX, arg_start[2]
  INT 21h
  JC Error1
  MOV outfile, AX

  MOV AH, WRITE
  MOV BX, outfile
  MOV CX, HTML_START_LEN
  LEA DX, html_start
  INT 21h
  JC Error1
  
  MOV AH, READ
  MOV BX, infile
  MOV CX, BUFSIZE
  LEA DX, buffer1
  INT 21h
  JC Error1

  CMP AX, 0
  JE Error1
  MOV isviso_symb, AX
  CMP AX, BUFSIZE
  JNE GenerateHTML

  MOV AH, READ
  MOV BX, infile
  MOV CX, BUFSIZE
  LEA DX, buffer2
  INT 21h
  JC Error1
  ADD isviso_symb, AX
  JMP GenerateHTML

Error1:
  JMP Error

GenerateHTML:
  MOV AX, curr_symb_nr
  MOV start_symb_nr, AX
  CALL get_asm_word
  MOV highlight_type, 0




  ;komentarai
  CMP bendras_highlight_type, 7
  JE rastas_bendras_komentaras
  LEA BX, buffer1
  MOV SI, start_symb_nr
  CMP byte ptr [BX+SI], ';'
  JE init_rastas_komentaras
  JMP testi_highlight_tikrinima2
rastas_bendras_komentaras:
  LEA BX, buffer1
  MOV SI, curr_symb_nr
  SUB SI, 1
  CMP byte ptr [BX+SI], 0Dh
  JNE rastas_komentaras
  MOV bendras_highlight_type, 0
  JMP rastas_komentaras
init_rastas_komentaras:
  MOV bendras_highlight_type, 7
rastas_komentaras:
  LEA AX, spalva_pradzia_komentaras
  MOV sht_spalva_pradzia, AX
  MOV highlight_type, 7  
  JMP testi_GenerateHTML
  




  ;kabutes
testi_highlight_tikrinima2:
  LEA BX, buffer1
  MOV SI, start_symb_nr
  CMP byte ptr [BX+SI], 27h
  JE init_bendras_highlight_type
  MOV SI, curr_symb_nr
  SUB SI, 1
  CMP byte ptr [BX+SI], 27h
  JE init_bendras_highlight_type
  CMP bendras_highlight_type, 6
  JE rasta_kabute
  JMP testi_highlight_tikrinima
init_bendras_highlight_type:
  CMP bendras_highlight_type, 6
  JNE ivesti_bht
  MOV bendras_highlight_type, 0
  JMP rasta_kabute  
ivesti_bht:
  MOV bendras_highlight_type, 6
rasta_kabute:
  LEA AX, spalva_pradzia_kabute
  MOV sht_spalva_pradzia, AX
  MOV highlight_type, 6
  JMP testi_GenerateHTML
  
  


  ;label'ai
testi_highlight_tikrinima:
  MOV SI, curr_symb_nr
  SUB SI, 1
  LEA BX, buffer1
  CMP byte ptr [BX+SI], ':'
  JE sugeneruoti_label
  JMP testi_tikrinima
sugeneruoti_label:
  LEA AX, spalva_pradzia_label_var
  MOV sht_spalva_pradzia, AX
  MOV highlight_type, 4
  JMP testi_GenerateHTML

  

testi_tikrinima:
  MOV sht_highlight_type, 1
  MOV sht_TASM_WORDS_LEN, TASM_DIR_LEN
  LEA AX, tasm_directives
  MOV sht_tasm_words_adr, AX
  LEA AX, spalva_pradzia_dir
  MOV sht_spalva_pradzia, AX
  CALL scan_highlight_type
  CMP highlight_type, 0
  JNE testi_GenerateHTML1
  
  MOV sht_highlight_type, 2
  MOV sht_TASM_WORDS_LEN, TASM_INS_LEN
  LEA AX, tasm_instructions
  MOV sht_tasm_words_adr, AX
  LEA AX, spalva_pradzia_ins
  MOV sht_spalva_pradzia, AX
  CALL scan_highlight_type
  CMP highlight_type, 0
  JNE testi_GenerateHTML1

  MOV sht_highlight_type, 3
  MOV sht_TASM_WORDS_LEN, TASM_REG_LEN
  LEA AX, tasm_registers
  MOV sht_tasm_words_adr, AX
  LEA AX, spalva_pradzia_reg
  MOV sht_spalva_pradzia, AX
  CALL scan_highlight_type
  CMP highlight_type, 0
  JNE testi_GenerateHTML
  JMP testi_tikrinima2

testi_GenerateHTML1:
  JMP testi_GenerateHTML

  

;skaiciai
testi_tikrinima2:
  LEA BX, buffer1
  MOV SI, start_symb_nr
  MOV CX, curr_symb_nr
  SUB CX, start_symb_nr  
  SUB CX, 1
  MOV AX, CX
skaiciu_tikrinimo_ciklas:
  CMP CX, AX
  JE pirmas_skaitmuo
  CMP CX, 1
  JE paskutinis_skaitmuo
  JMP bendras_tikrinimas

pirmas_skaitmuo:
  CMP byte ptr [BX+SI], '-'
  JE testi_skaiciu_tikrinimo_cikla
  JMP bendras_tikrinimas

paskutinis_skaitmuo:
  CMP byte ptr [BX+SI], 'b'
  JE testi_skaiciu_tikrinimo_cikla
  CMP byte ptr [BX+SI], 'o'
  JE testi_skaiciu_tikrinimo_cikla
  CMP byte ptr [BX+SI], 'h'
  JE testi_skaiciu_tikrinimo_cikla

bendras_tikrinimas:
  CMP byte ptr [BX+SI], '0'
  JGE testi_bendra_tikrinima1
  JMP testi_spalvos_tikrinima
testi_bendra_tikrinima1:
  CMP byte ptr [BX+SI], '9'
  JBE testi_skaiciu_tikrinimo_cikla
  JMP testi_bendra_tikrinima2
testi_bendra_tikrinima2:
  CMP byte ptr [BX+SI], 'A'
  JGE testi_bendra_tikrinima3
  JMP testi_spalvos_tikrinima
testi_bendra_tikrinima3:
  CMP byte ptr [BX+SI], 'F'
  JBE testi_skaiciu_tikrinimo_cikla
  JMP testi_spalvos_tikrinima
  
testi_skaiciu_tikrinimo_cikla:
  INC SI
  LOOP skaiciu_tikrinimo_ciklas
  MOV highlight_type, 5
  LEA AX, spalva_pradzia_sk
  MOV sht_spalva_pradzia, AX
  JMP testi_GenerateHTML



testi_spalvos_tikrinima:
testi_GenerateHTML:
  CMP highlight_type, 0
  JNE spalva_pradzia_label
  JMP testi_GenerateHTML2

spalva_pradzia_label:
  MOV AH, WRITE
  MOV BX, outfile
  MOV CX, SPALVA_PRADZIA_LEN
  MOV DX, sht_spalva_pradzia
  INT 21h
  JC Error2

testi_GenerateHTML2:
  MOV AH, WRITE
  MOV BX, outfile
  MOV CX, curr_symb_nr
  SUB CX, start_symb_nr
  CMP CX, 0
  JNE atmesti_viena_simboli
  JMP neatmesti_viena_simboli
atmesti_viena_simboli:
  SUB CX, 1
neatmesti_viena_simboli:
  LEA DX, buffer1
  ADD DX, start_symb_nr
  INT 21h
  JC Error2
  
  CMP highlight_type, 0
  JNE spalva_pabaiga_label
  JMP testi_GenerateHTML3

Error2:
  JMP Error

spalva_pabaiga_label:
  MOV AH, WRITE
  MOV BX, outfile
  MOV CX, SPALVA_PABAIGA_LEN
  LEA DX, spalva_pabaiga
  INT 21h
  JC Error2
 
testi_GenerateHTML3:
  MOV AX, curr_symb_nr
  CMP AX, start_symb_nr
  JNE isvesti_paskutini_simboli
  JMP neisvesti_paskutini_simboli

GenerateHTML1:
  JMP GenerateHTML

isvesti_paskutini_simboli:
  MOV AH, WRITE
  MOV BX, outfile
  MOV CX, 1
  LEA DX, buffer1
  ADD DX, curr_symb_nr
  SUB DX, 1
  INT 21h
  JC Error2
neisvesti_paskutini_simboli:
  CMP isviso_symb, BUFSIZE
  JNB cmp_bufsize
  MOV AX, isviso_symb
  CMP curr_symb_nr, AX
  JMP cmp_bendras  
cmp_bufsize:
  CMP curr_symb_nr, BUFSIZE
cmp_bendras:
  JNG GenerateHTML1

  CMP isviso_symb, BUFSIZE
  JB EndHTML

;apnulinu symb_nr
  CMP curr_symb_nr, BUFSIZE
  JG sub_bufsize
  MOV curr_symb_nr, 0
  JMP toliau
sub_bufsize:
  SUB curr_symb_nr, BUFSIZE
toliau:
  MOV AX, curr_symb_nr
  MOV start_symb_nr, AX

;bufer2 -> bufer1
  CLD
  LEA SI, buffer2
  LEA DI, buffer1
  MOV CX, BUFSIZE
  REP MOVSB

  SUB isviso_symb, BUFSIZE
  CMP isviso_symb, BUFSIZE
  JB GenerateHTML1

  MOV AH, READ
  MOV BX, infile
  MOV CX, BUFSIZE
  LEA DX, buffer2
  INT 21h
  JC Error
  ADD isviso_symb, AX
  JMP GenerateHTML
  
EndHTML:
  MOV AH, WRITE
  MOV BX, outfile
  MOV CX, HTML_END_LEN
  LEA DX, html_end
  INT 21h
  JC Error  
  
quit:
  MOV AH, EXIT
  XOR AL, AL
  INT 21h
  
error:
  LEA DX, error_msg
  MOV AH, PRINT
  INT 21h
  JMP quit
  
MAIN ENDP

  get_params PROC NEAR
    PUSH DS
    PUSH AX
    PUSH BX

    MOV AH, GETPSP
    INT 21h

    MOV DS, BX
    MOV CL, [DS:PARAM_LINE]
    MOV DI, offset params
    MOV SI, PARAM_LINE+1
    XOR CH, CH

    CLD
    REP MOVSB

    MOV CL, [DS:PARAM_LINE]
    MOV AX, DSEG
    MOV DS, AX
    XOR SI, SI
    XOR BP, BP
    MOV AL, SPACE
    MOV DI, offset params
loop0:
    REPNE SCASB

    JCXZ end0
    MOV arg_start[SI], DI
    DEC DI
    MOV byte ptr [DI], 0
    ADD SI, 2
    INC BP
    JMP loop0

end0:
    MOV [arg_count], BP
    POP BX
    POP AX
    POP DS
    RET
  get_params ENDP

  get_asm_word PROC NEAR
    PUSH CX    
    PUSH AX
    PUSH BX
    MOV CX, isviso_symb
word_loop:
    MOV SI, curr_symb_nr
    MOV AL, buffer1[SI]
    MOV curr_symb, AL
    MOV BX, CX
    XOR CH, CH
    MOV CL, sep_count
  symb_loop:
    MOV SI, CX
    MOV AL, separators[SI-1]
    CMP curr_symb, AL
    JE exit_proc_find
  LOOP symb_loop
    MOV CX, BX
    INC curr_symb_nr
LOOP word_loop
    JMP exit_proc
exit_proc_find:
    MOV CX, BX
    INC curr_symb_nr
exit_proc:
    POP BX
    POP AX
    POP CX
    RET
  get_asm_word ENDP

  scan_highlight_type PROC NEAR
    PUSH AX
    PUSH CX
    PUSH DI
    PUSH SI
  
    MOV start_symb_nr_tasm, -1
    MOV symb_ilgis_tasm, 0
highlight_directives:
    MOV AX, symb_ilgis_tasm
    ADD start_symb_nr_tasm, AX
    ADD start_symb_nr_tasm, 1
    MOV AL, ' '
    MOV CX, sht_TASM_WORDS_LEN
    SUB CX, start_symb_nr_tasm
    MOV DI, sht_tasm_words_adr
    ADD DI, start_symb_nr_tasm
    REPNE SCASB
    JNE end_sht

    DEC DI
    MOV AX, DI
    MOV DI, sht_tasm_words_adr
    SUB AX, DI
    SUB AX, start_symb_nr_tasm
    MOV CX, curr_symb_nr
    SUB CX, start_symb_nr
    SUB CX, 1
    MOV symb_ilgis_tasm, AX
    CMP AX, CX
    JNE highlight_directives

    LEA SI, buffer1
    ADD SI, start_symb_nr
    ADD DI, start_symb_nr_tasm
    REPE CMPSB
    JNE highlight_directives
    MOV AL, sht_highlight_type
    MOV highlight_type, AL

end_sht:
    POP SI
    POP DI
    POP CX
    POP AX
    RET
  scan_highlight_type ENDP

CSEG ENDS
END MAIN
